home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 February / EnigmA AMIGA RUN 15 (1997)(G.R. Edizioni)(IT)[!][issue 1997-02][PLANET CD V].iso / enigma / earcd / emula / arosdv19.lha / AROS / intuition / buttongclass.c < prev    next >
C/C++ Source or Header  |  1996-10-30  |  10KB  |  419 lines

  1. /* AROS buttongclass implementation
  2.  * (frameless button, no window border support yet)
  3.  * 10/26/96 caldi@usa.nai.net
  4.  */
  5.  
  6. #include <exec/types.h>
  7.  
  8. #include <dos/dos.h>
  9. #include <dos/dosextens.h>
  10.  
  11. #include <intuition/intuition.h>
  12. #include <intuition/intuitionbase.h>
  13. #include <intuition/classes.h>
  14. #include <intuition/classusr.h>
  15. #include <intuition/gadgetclass.h>
  16. #include <intuition/cghooks.h>
  17. #include <intuition/icclass.h>
  18. #include <intuition/imageclass.h>
  19.  
  20. #include <graphics/gfxbase.h>
  21. #include <graphics/gfxmacros.h>
  22.  
  23. #include <utility/tagitem.h>
  24. #include <utility/hooks.h>
  25.  
  26. #include <clib/macros.h>
  27.  
  28. #ifdef _SASC
  29. #include <proto/exec.h>
  30. #include <proto/intuition.h>
  31. #include <proto/graphics.h>
  32. #include <proto/utility.h>
  33. #elif __GNUC__
  34. #include <clib/exec_protos.h>
  35. #include <clib/intuition_protos.h>
  36. #include <clib/graphics_protos.h>
  37. #include <clib/utility_protos.h>
  38. #endif
  39.  
  40. #ifdef _AROS
  41. #include <aros/asmcall.h>
  42. #include <clib/alib_protos.h>
  43. #include "intuition_intern.h"
  44. #include "gadgets.h"
  45. #endif
  46.  
  47. /****************************************************************************/
  48.  
  49. /* Some handy transparent base class object casting defines.
  50.  */
  51. #define G(o)  ((struct Gadget *)o)
  52. #define EG(o) ((struct ExtGadget *)o)
  53. #define IM(o) ((struct Image *)o)
  54.  
  55. /****************************************************************************/
  56.  
  57.  
  58. #undef IntuitionBase
  59. #define IntuitionBase    ((struct IntuitionBase *)(cl->cl_UserData))
  60.  
  61. /* buttongclass boopsi dispatcher
  62.  */
  63. AROS_UFH3(static IPTR, dispatch_buttongclass,
  64.     AROS_UFHA(Class *,  cl,  A0),
  65.     AROS_UFHA(Object *, o,   A2),
  66.     AROS_UFHA(Msg,      msg, A1)
  67. )
  68. {
  69.     IPTR retval = 0UL;
  70.  
  71.     switch(msg->MethodID)
  72.     {
  73.     case GM_RENDER:
  74.     /* We will let the AROS gadgetclass test if it is safe to render */
  75.     if ( DoSuperMethodA(cl, o, msg) != 0)
  76.     {
  77.         UWORD *pens = ((struct gpRender *)msg)->gpr_GInfo->gi_DrInfo->dri_Pens;
  78.         struct RastPort *rp = ((struct gpRender *)msg)->gpr_RPort;
  79.         struct IBox container;
  80.  
  81.         GetGadgetIBox(o, ((struct gpRender *)msg)->gpr_GInfo, &container);
  82.  
  83.         if (container.Width <= 1 || container.Height <= 1)
  84.         return(retval);
  85.  
  86.         if ( EG(o)->Flags & GFLG_SELECTED )
  87.         {
  88.         SetAPen( rp, pens[FILLPEN] );
  89.         }
  90.         else
  91.         {
  92.         SetAPen( rp, pens[BACKGROUNDPEN] );
  93.         } /* if */
  94.  
  95.         SetDrMd( rp, JAM1 );
  96.  
  97.         RectFill( rp,
  98.         container.Left,
  99.         container.Top,
  100.         container.Left + container.Width - 1,
  101.         container.Top + container.Height - 1
  102.         );
  103.  
  104.         if ( (EG(o)->Flags & GFLG_GADGIMAGE) == 0 )
  105.         {
  106.         if ( ( EG(o)->SelectRender != NULL ) && ( EG(o)->Flags & GFLG_SELECTED ) )
  107.         {
  108.             DrawBorder(rp, ((struct Border *)EG(o)->SelectRender), container.Left, container.Top );
  109.         }
  110.         else if ( EG(o)->GadgetRender != NULL )
  111.         {
  112.             DrawBorder(rp, ((struct Border *)EG(o)->GadgetRender), container.Left, container.Top );
  113.         }
  114.         }
  115.         else if ( EG(o)->Flags & GFLG_GADGIMAGE )
  116.         {
  117.         if ( ( EG(o)->SelectRender != NULL ) && ( EG(o)->Flags & GFLG_SELECTED ) )
  118.         {
  119.             /* center image position, we assume image top and left is 0 */
  120.             ULONG x = container.Left + ((container.Width / 2) - (IM(EG(o)->SelectRender)->Width / 2));
  121.             ULONG y = container.Top + ((container.Height / 2) - (IM(EG(o)->SelectRender)->Height / 2));
  122.  
  123.             DrawImageState( rp,
  124.             IM(EG(o)->SelectRender),
  125.             x, y,
  126.             ( (EG(o)->Flags & GFLG_SELECTED) ? IDS_SELECTED : IDS_NORMAL ),
  127.             ((struct gpRender *)msg)->gpr_GInfo->gi_DrInfo );
  128.         }
  129.         else if ( EG(o)->GadgetRender != NULL )
  130.         {
  131.             /* center image position, we assume image top and left is 0 */
  132.             ULONG x = container.Left + ((container.Width / 2) - (IM(EG(o)->GadgetRender)->Width / 2));
  133.             ULONG y = container.Top + ((container.Height / 2) - (IM(EG(o)->GadgetRender)->Height / 2));
  134.  
  135.             DrawImageState( rp,
  136.             IM(EG(o)->GadgetRender),
  137.             x, y,
  138.             ( (EG(o)->Flags & GFLG_SELECTED) ? IDS_SELECTED : IDS_NORMAL ),
  139.             ((struct gpRender *)msg)->gpr_GInfo->gi_DrInfo );
  140.         }
  141.         }
  142.  
  143.         switch (EG(o)->Flags & GFLG_LABELMASK)
  144.         {
  145.         case GFLG_LABELITEXT:
  146.             PrintIText( rp, EG(o)->GadgetText, container.Left, container.Top );
  147.             break;
  148.  
  149.         case GFLG_LABELSTRING:
  150.             if( EG(o)->GadgetText != NULL )
  151.             {
  152.             ULONG len;
  153.  
  154.             if ((len = strlen ((STRPTR) EG(o)->GadgetText)) > 0UL)
  155.             {
  156.                 ULONG x;
  157.                 ULONG y;
  158.  
  159.                 x = container.Left + (container.Width / 2);
  160.                 x -= LabelWidth (rp, (STRPTR) EG(o)->GadgetText, len, IntuitionBase) / 2;
  161.  
  162.                 y = container.Top + (container.Height / 2) + rp->Font->tf_Baseline;
  163.                 y -= rp->Font->tf_YSize / 2;
  164.  
  165.                 SetAPen (rp, pens[TEXTPEN] );
  166.  
  167.                 Move (rp, x, y );
  168.                 RenderLabel (rp, (STRPTR) EG(o)->GadgetText, len, IntuitionBase);
  169.             }
  170.             }
  171.             break;
  172.  
  173.         case GFLG_LABELIMAGE:
  174.             {
  175.             /* center image position, we assume image top and left is 0 */
  176.             ULONG x = container.Left + ((container.Width / 2) - (IM(EG(o)->GadgetText)->Width / 2));
  177.             ULONG y = container.Top + ((container.Height / 2) - (IM(EG(o)->GadgetText)->Height / 2));
  178.  
  179.             DrawImageState( rp,
  180.                 IM(EG(o)->GadgetText),
  181.                 x, y,
  182.                 ( (EG(o)->Flags & GFLG_SELECTED) ? IDS_SELECTED : IDS_NORMAL ),
  183.                 ((struct gpRender *)msg)->gpr_GInfo->gi_DrInfo );
  184.             }
  185.             break;
  186.         }
  187.  
  188.         if ( EG(o)->Flags & GFLG_DISABLED )
  189.         {
  190.         UWORD pattern[] = { 0x8888, 0x2222 };
  191.  
  192.         SetDrMd( rp, JAM1 );
  193.         SetAPen( rp, pens[SHADOWPEN] );
  194.         SetAfPt( rp, pattern, 1);
  195.  
  196.         /* render disable pattern */
  197.         RectFill( rp,
  198.             container.Left,
  199.             container.Top,
  200.             container.Left + container.Width - 1,
  201.             container.Top + container.Height - 1 );
  202.         } /* if */
  203.     } /* if */
  204.     break;
  205.  
  206.     case GM_LAYOUT:
  207.     break;
  208.  
  209.     case GM_DOMAIN:
  210.     break;
  211.  
  212.     case GM_GOACTIVE:
  213.     {
  214.         struct GadgetInfo *gi = ((struct gpInput *)msg)->gpi_GInfo;
  215.  
  216.         if (gi)
  217.         {
  218.         struct RastPort *rp = ObtainGIRPort(gi);
  219.         if (rp)
  220.         {
  221.             EG(o)->Flags |= GFLG_SELECTED;
  222.  
  223.             DoMethod(o, GM_RENDER, gi, rp, GREDRAW_REDRAW);
  224.             ReleaseGIRPort(rp);
  225.  
  226.             DoMethod(o, OM_NOTIFY, gi, NULL, OPUF_INTERIM);
  227.  
  228.             retval = GMR_MEACTIVE;
  229.         } /* if */
  230.         } /* if */
  231.     } /* if */
  232.     break;
  233.  
  234.     case GM_HANDLEINPUT:
  235.     {
  236.         struct GadgetInfo *gi = ((struct gpInput *)msg)->gpi_GInfo;
  237.  
  238.         if (gi)
  239.         {
  240.         struct InputEvent *ie = ((struct gpInput *)msg)->gpi_IEvent;
  241.  
  242.         retval = GMR_MEACTIVE;
  243.  
  244.         switch( ie->ie_Class )
  245.         {
  246.         case IECLASS_RAWMOUSE:
  247.             switch( ie->ie_Code )
  248.             {
  249.             case MENUDOWN:
  250.             retval = GMR_REUSE;
  251.             *((struct gpInput *)msg)->gpi_Termination = 0UL;
  252.             break;
  253.  
  254.             case SELECTUP:
  255.             if( EG(o)->Flags & GFLG_SELECTED )
  256.             {
  257.                 retval = GMR_NOREUSE | GMR_VERIFY;
  258.                 *((struct gpInput *)msg)->gpi_Termination = 1UL;
  259.             }
  260.             else
  261.             {
  262.                 retval = GMR_NOREUSE;
  263.                 *((struct gpInput *)msg)->gpi_Termination = 0UL;
  264.             } /* if */
  265.             break;
  266.  
  267.             case IECODE_NOBUTTON: {
  268.             struct gpHitTest gpht;
  269.  
  270.             gpht.MethodID      = GM_HITTEST;
  271.             gpht.gpht_GInfo   = gi;
  272.             gpht.gpht_Mouse.X = ((struct gpInput *)msg)->gpi_Mouse.X;
  273.             gpht.gpht_Mouse.Y = ((struct gpInput *)msg)->gpi_Mouse.Y;
  274.  
  275.             /*
  276.                 This case handles selection state toggling when the
  277.                 left button is depressed and the mouse is moved
  278.                 around on/off the gadget bounds.
  279.             */
  280.             if ( DoMethodA(o, (Msg)&gpht) == GMR_GADGETHIT )
  281.             {
  282.                 if ( (EG(o)->Flags & GFLG_SELECTED) == 0 )
  283.                 {
  284.                 struct RastPort *rp;
  285.  
  286.                 /* mouse is over gadget */
  287.                 EG(o)->Flags |= GFLG_SELECTED;
  288.  
  289.                 if ((rp = ObtainGIRPort(gi)))
  290.                 {
  291.                     DoMethod(o, GM_RENDER, gi, rp, GREDRAW_UPDATE);
  292.                     ReleaseGIRPort(rp);
  293.                 } /* if */
  294.                 } /* if */
  295.             }
  296.             else
  297.             {
  298.                 if ( (EG(o)->Flags & GFLG_SELECTED) != 0 )
  299.                 {
  300.                 struct RastPort *rp;
  301.  
  302.                 /* mouse is not over gadget */
  303.                 EG(o)->Flags &= ~GFLG_SELECTED;
  304.  
  305.                 if ((rp = ObtainGIRPort(gi)))
  306.                 {
  307.                     DoMethod(o, GM_RENDER, gi, rp, GREDRAW_UPDATE);
  308.                     ReleaseGIRPort(rp);
  309.                 } /* if */
  310.                 } /* if */
  311.             } /* if */
  312.             break; }
  313.  
  314.             } /* switch */
  315.  
  316.             break;
  317.  
  318.         case IECLASS_TIMER:
  319.             if (EG(o)->Flags & GFLG_SELECTED)
  320.             {
  321.             DoMethod(o, OM_NOTIFY, NULL, gi, OPUF_INTERIM);
  322.             } /* if */
  323.             break;
  324.         } /* switch */
  325.         }
  326.         else
  327.         {
  328.         /* if we get here something is *really* wrong */
  329.         retval = GMR_NOREUSE;
  330.         } /* if */
  331.     } /* if */
  332.     break;
  333.  
  334.     case GM_GOINACTIVE:
  335.     EG(o)->Flags &= ~GFLG_SELECTED;
  336.     {
  337.         struct GadgetInfo *gi = ((struct gpGoInactive *)msg)->gpgi_GInfo;
  338.  
  339.         if (gi)
  340.         {
  341.         struct RastPort *rp = ObtainGIRPort(gi);
  342.         if (rp)
  343.         {
  344.             DoMethod(o, GM_RENDER, gi, rp, GREDRAW_REDRAW);
  345.             ReleaseGIRPort(rp);
  346.  
  347.             DoMethod(o, OM_NOTIFY, NULL, gi, 0);
  348.         } /* if */
  349.         } /* if */
  350.     } /* if */
  351.     break;
  352.  
  353.     case OM_NEW:
  354.     retval = DoSuperMethodA(cl, o, msg);
  355.  
  356.     if (retval)
  357.     {
  358.         /* Handle our special tags - overrides defaults */
  359.         /* set_buttongclass(cl, (Object *)retval, (struct opSet *)msg); */
  360.     } /* if */
  361.     break;
  362.  
  363.     case OM_SET:
  364.     case OM_UPDATE:
  365.     retval = DoSuperMethodA(cl, o, msg);
  366.  
  367.     /* If we have been subclassed, OM_UPDATE should not cause a GM_RENDER
  368.         * because it would circumvent the subclass from fully overriding it.
  369.         * The check of cl == OCLASS(o) should fail if we have been
  370.         * subclassed, and we have gotten here via DoSuperMethodA().
  371.         */
  372.     if ( retval && ( msg->MethodID == OM_UPDATE ) && ( cl == OCLASS(o) ) )
  373.     {
  374.         struct GadgetInfo *gi = ((struct opSet *)msg)->ops_GInfo;
  375.         if (gi)
  376.         {
  377.         struct RastPort *rp = ObtainGIRPort(gi);
  378.         if (rp)
  379.         {
  380.             DoMethod(o, GM_RENDER, gi, rp, GREDRAW_REDRAW);
  381.             ReleaseGIRPort(rp);
  382.         } /* if */
  383.         } /* if */
  384.     } /* if */
  385.     break;
  386.  
  387.     default:
  388.     retval = DoSuperMethodA(cl, o, msg);
  389.     break;
  390.     } /* switch */
  391.  
  392.     return retval;
  393. }  /* dispatch_buttongclass */
  394.  
  395.  
  396. #undef IntuitionBase
  397.  
  398. /****************************************************************************/
  399.  
  400. /* Initialize our image class. */
  401. struct IClass *InitButtonGClass (struct IntuitionBase * IntuitionBase)
  402. {
  403.     struct IClass *cl = NULL;
  404.  
  405.     /* This is the code to make the buttongclass...
  406.     */
  407.     if ( (cl = MakeClass(BUTTONGCLASS, GADGETCLASS, NULL, 0, 0)) )
  408.     {
  409.     cl->cl_Dispatcher.h_Entry    = (APTR)AROS_ASMFUNC_NAME(dispatch_buttongclass);
  410.     cl->cl_Dispatcher.h_SubEntry = NULL;
  411.     cl->cl_UserData          = (IPTR)IntuitionBase;
  412.  
  413.     AddClass (cl);
  414.     }
  415.  
  416.     return (cl);
  417. }
  418.  
  419.